#define _WITH_WIRING_PI 1

#if _WITH_WIRING_PI
#include <wiringPi.h>
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <thread>
#include <iostream>

//#include "lvx_file.h"
//#include "time_info.h"
//#include "gprmc.h"

#define TOUCH_OUT_PIN 27
#define TOUCH_IN_PIN 26

int flag_exit_pps = 0;

#define USE_ISR_PIN 1

volatile int rising_flag = 0;

#if !_WITH_WIRING_PI
   typedef unsigned char u8;
#endif

extern void BCC(u8 *data,u8 *res);

void BCC(u8 *data,u8 *res){
	int len = strlen((char*)data);
	u8 checknum = '\0';
	int i=1;
	for(i=1;i<len-1;i++){
		checknum = checknum ^ data[i];
	}
	
	sprintf((char*)res,"%02x",checknum&0x00ff);
	
} 


void savePackage_pps(char * str_in)
{
    char * buff_write = (char *)malloc(128); 
    memset(buff_write,0,128);
    int len_str = strlen(str_in);    
    char * ptr_data = buff_write;    
    unsigned char sum[4];		
    printf("pps save:%s\r\n",str_in);    
    buff_write[0] = 0x7b;    
    buff_write[1] = 0x04;    
    buff_write[2] = len_str + 3;    
    buff_write[3] = 0x00;    
    buff_write[4] = 0x00;    
    buff_write[5] = 0x00;    
    memcpy(buff_write+6,str_in,len_str);       
    BCC((unsigned char *)str_in,sum);    
    buff_write[6+len_str] = '*';    
    buff_write[7+len_str] = sum[0];    
    buff_write[8+len_str] = sum[1];    
    ptr_data += (len_str + 9);        
    *ptr_data = 0x0d;    
    ptr_data++;    
    *ptr_data = 0x0a;    
    //pthread_mutex_lock(&mutex_file_wr);    
    //write_to_lvx((unsigned char *)buff_write, len_str+11,1);    
    //pthread_mutex_unlock(&mutex_file_wr);
    rising_flag = 0;
    free(buff_write);
    
}


void myInterrupt0 (void) 
{ 
    rising_flag = 1; 
}

char str_rise_time[64];
void main_pps(void)
{
    char buff[128];
    char buff_time[64];
#if _WITH_WIRING_PI
    if(wiringPiSetup()==-1)
    {
        printf("pps , wiring setup failed\n");
        return;
     }
    pinMode(TOUCH_IN_PIN,INPUT);
    pullUpDnControl(TOUCH_IN_PIN,PUD_UP);
    pinMode(TOUCH_OUT_PIN,OUTPUT);
#endif
    //pinMode(TOUCH_OUT_PIN,OUTPUT);
    //digitalWrite(TOUCH_OUT_PIN,HIGH);
    flag_exit_pps = 0;
    //volatile int currState = 0;
    //volatile int lastState = 0;
	
	//g_run_duration->get_delta_str(str_rise_time); 

    //struct timeval curr_tv;
    //struct tm date_time_now;
    
#if _WITH_WIRING_PI
    wiringPiISR (TOUCH_IN_PIN, INT_EDGE_RISING, &myInterrupt0) ;
#endif
   // currState = digitalRead(TOUCH_IN_PIN);

    //printf("currState is:%d\r\n",currState);

    while(!flag_exit_pps)
    {
        if(rising_flag)
        {
            printf("pps rising edge\r\n");
            rising_flag = 0;
            //g_run_duration->get_delta_str(str_rise_time);   
            savePackage_pps("$,20220322.345,34.809*78");
        }
    }
      return;
}


void gen_pulse_func(void)
{
#if _WITH_WIRING_PI
    pinMode(TOUCH_OUT_PIN,OUTPUT);
    digitalWrite(TOUCH_OUT_PIN,LOW);
    while(1)
    {
        sleep(1);
        digitalWrite(TOUCH_OUT_PIN,HIGH);
        usleep(100);
        digitalWrite(TOUCH_OUT_PIN,LOW);
    }
#endif
    //return NULL;
}

int main_test1(void)
{
    char buff[128];
    char buff_time[64];

    struct timeval curr_tv;
    struct tm date_time_now;

    gettimeofday(&curr_tv, NULL);
      time_t time_now = curr_tv.tv_sec;

      localtime_r(&curr_tv.tv_sec,&date_time_now);                  

      buff[0] = '$';
      strftime(buff_time,64,"%Y%m%d%H%M%S",&date_time_now);
      sprintf(buff,"$%s.%03ld,",buff_time,curr_tv.tv_usec/1000);
      printf("aa is %s\r\n",buff);
    sleep(1);

        gettimeofday(&curr_tv, NULL);
        time_now = curr_tv.tv_sec;
        
        localtime_r(&curr_tv.tv_sec,&date_time_now);                  
        strftime(buff_time,64,"%Y%m%d%H%M%S",&date_time_now);
        sprintf(buff,"%s%s.%03ld",buff,buff_time,curr_tv.tv_usec/1000);
    printf("%s\r\n",buff);
      
    return 0;
}

int main(void)
{
    std::thread gen_pulse_thread(gen_pulse_func);    
    std::thread pps_thread(main_pps);

    gen_pulse_thread.join();
    pps_thread.join();
    
    return 0;
}

//connect pin12 and pin16
//g++ -o pps_test pps_test.cpp -std=gnu++11 -lpthread